#pragma once

#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream>
#include <cstring>
#include <thread>
#include <map>
#include <set>
#include <curl/curl.h>
#include <openssl/hmac.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <nlohmann/json.hpp>
#include "fmtlog.h"

using client = websocketpp::client<websocketpp::config::asio_tls_client>;
using context_ptr = std::shared_ptr<boost::asio::ssl::context>;
using websocketpp::lib::bind;
using websocketpp::lib::placeholders::_1;
using message_ptr = websocketpp::config::asio_client::message_type::ptr;

struct CoinTick {
    std::string symbol;
    double ask1;
    double bid1;
    CoinTick() {}
    CoinTick(std::string a, double b, double c) : symbol(a), ask1(b), bid1(c) {}
};

class BinanceData {
public:
    static BinanceData* getInstance();
    void addCoinTick(std::string inst, double ask, double bid);
    double getPrice(const std::string& inst, const char& type);
    std::vector<std::string> getSymbols();
    void connect();

protected:
    void run_data_client();
    void on_data_message(websocketpp::connection_hdl hdl, message_ptr msg);
    void on_data_open(websocketpp::connection_hdl hdl);
    void on_data_close(websocketpp::connection_hdl hdl);

private:
    static BinanceData* dataHandler;
    std::map<std::string, CoinTick> coinMp;
    client m_data_client;
    client m_trade_client;
    std::string dataUrl = "wss://stream.binance.com:9443/ws/!ticker@arr";
    BinanceData();
};